includes("toolchains/*.lua")

add_rules("mode.debug", "mode.release", "mode.releasedbg")


set_runtimes("MD") -- Windows
set_policy("build.cuda.devlink", true)   -- 默认就是 true，可省

-- 添加第三方依赖库
-- add_requires("fmt", "spdlog", "zlib 1.3.1", {configs = {shared = true}})
add_requires("fmt", "spdlog", "zlib 1.3.1")

-- 添加自动生成compile_commands.json的规则，为clangd提供编译数据库
add_rules("plugin.compile_commands.autoupdate", {outputdir = "./"})
-- 生成 compile_commands.json 文件
target("generate_compile_commands")
    set_kind("phony")
    on_run(function (target)
        os.exec("xmake project -k compile_commands")
    end)


target("cutest")
    set_kind("binary")
    set_languages("c++20")
    add_files("src/*.cu")
    add_files("src/*.cpp")
    add_headerfiles("src/*.cuh", {install = false})
    add_packages("fmt", "spdlog", "zlib 1.3.1")

    -- 设置使用动态链接的运行时库
    if is_plat("windows") then
        set_runtimes("MD")
    -- else if is_plat("linux") then
        -- set_runtimes("c++_shared")
    else
        set_runtimes("c++_shared")
    end

    -- 在Windows平台下为cl编译器和nvcc设置UTF-8编码选项
    if is_plat("windows") then
        -- 直接传递给cl编译器的UTF-8选项
        add_cxxflags("/utf-8")
        -- 通过-Xcompiler参数传递给nvcc的UTF-8选项
        -- 传递给nvcc的宏定义 FMT_UNICODE=0
        add_cuflags("-Xcompiler=/utf-8 -DFMT_UNICODE=0")

        ---- 为nvcc添加抑制警告的编译标志
        -- add_cuflags("-diag-suppress=27")   -- 抑制fmt中的字符值超出范围警告
        -- add_cuflags("-diag-suppress=128")  -- 抑制fmt中的"loop is not reachable"警告
        -- add_cuflags("-diag-suppress=2417") -- 抑制fmt中的constexpr构造函数警告
        -- add_cuflags("-diag-suppress=1388") -- 抑制spdlog中的DLL接口规范不一致警告
        -- add_cuflags("-diag-suppress=1394") -- 抑制spdlog中的DLL接口字段警告
    end

    -- generate SASS code for SM architecture of current host
    add_cugencodes("native")

    -- generate PTX code for the virtual architecture to guarantee compatibility
    -- add_cugencodes("compute_75")

    -- 构建后将依赖的DLL文件拷贝到二进制输出目录
    after_build(function (target)
        import("core.project.config")
        import("lib.detect.find_file")

        -- 获取输出目录（如：build/windows/x64/release）
        local outputdir = path.directory(target:targetfile())

        -- 遍历所有依赖包
        for _, pkg in ipairs(target:get("packages")) do
            print("[my] copy on pkg: " .. pkg)
            local pkg_info = target:pkg(pkg)
            if pkg_info then
                -- 获取包的 libfiles（包括 .dll）
                local libfiles = pkg_info:get("libfiles")
                if libfiles then
                    for _, dllpath in ipairs(libfiles) do
                        print("[my] " .. pkg .. " file: " .. dllpath)
                        if dllpath:endswith(".dll") then
                            local dllname = path.filename(dllpath)
                            local dest = path.join(outputdir, dllname)
                            if not os.isfile(dest) then
                                print("Copying " .. dllpath .. " -> " .. dest)
                                os.cp(dllpath, dest)
                            end
                        end
                    end
                end
            end
        end
    end)

    -- -- generate SASS code for each SM architecture
    -- add_cugencodes("sm_35", "sm_37", "sm_50", "sm_52", "sm_60", "sm_61", "sm_70", "sm_75")

    -- -- generate PTX code from the highest SM architecture to guarantee forward-compatibility
    -- add_cugencodes("compute_75")

--
-- If you want to known more usage about xmake, please see https://xmake.io
--
-- ## FAQ
--
-- You can enter the project directory firstly before building project.
--
--   $ cd projectdir
--
-- 1. How to build project?
--
--   $ xmake
--
-- 2. How to configure project?
--
--   $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
--
-- 3. Where is the build output directory?
--
--   The default output directory is `./build` and you can configure the output directory.
--
--   $ xmake f -o outputdir
--   $ xmake
--
-- 4. How to run and debug target after building project?
--
--   $ xmake run [targetname]
--   $ xmake run -d [targetname]
--
-- 5. How to install target to the system directory or other output directory?
--
--   $ xmake install
--   $ xmake install -o installdir
--
-- 6. Add some frequently-used compilation flags in xmake.lua
--
-- @code
--    -- add debug and release modes
--    add_rules("mode.debug", "mode.release")
--
--    -- add macro definition
--    add_defines("NDEBUG", "_GNU_SOURCE=1")
--
--    -- set warning all as error
--    set_warnings("all", "error")
--
--    -- set language: c99, c++11
--    set_languages("c99", "c++11")
--
--    -- set optimization: none, faster, fastest, smallest
--    set_optimize("fastest")
--
--    -- add include search directories
--    add_includedirs("/usr/include", "/usr/local/include")
--
--    -- add link libraries and search directories
--    add_links("tbox")
--    add_linkdirs("/usr/local/lib", "/usr/lib")
--
--    -- add system link libraries
--    add_syslinks("z", "pthread")
--
--    -- add compilation and link flags
--    add_cxflags("-stdnolib", "-fno-strict-aliasing")
--    add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
--
-- @endcode
--

